package mt.dummy;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import mt.Order;
import mt.comm.ClientComm;
import mt.comm.ClientSideMessage;
import mt.comm.ServerSideMessage;

/**
 * ClientCommDummy is used by the GUI of the client to communicate with the
 * server.
 * 
 * @author Pedro,Rita,Miguel
 *
 */
public class ClientCommDummy implements ClientComm {

	private Socket socket;

	private ObjectOutputStream out;
	private ObjectInputStream in;
	private BlockingQueue<ClientMessage> q = new ArrayBlockingQueue<ClientMessage>(
			100);
	private String nickname;
	private boolean isConnected = false;

	@Override
	public void connect(String serverAddress, String nickname) {
		this.nickname = nickname;
		try {
			socket = new Socket(serverAddress, ServerCommDummy.PORTO);
			in = new ObjectInputStream(socket.getInputStream());
			out = new ObjectOutputStream(socket.getOutputStream());
			isConnected = true;
			ServerMessage msg = new ServerMessage(
					ServerSideMessage.Type.CONNECTED, nickname, null);
			out.writeObject(msg);
			new Receive(in, out).start();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * This Threads receives and processed the ClientMessage.
	 */
	class Receive extends Thread {

		private ObjectInputStream in;
		//private ObjectOutputStream out;

		public Receive(ObjectInputStream in, ObjectOutputStream out) {
			this.in = in;
			//this.out = out;
		}

		@Override
		public void run() {
			try {
				while (isConnected()) {
					ClientMessage msg = (ClientMessage) in.readObject();
					System.out.println("ClientComm Recebe: " + msg.getOrder().toString());
					q.add(msg);
				}
			} catch (IOException e) {
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public boolean isConnected() {
		return isConnected;
	}

	@Override
	public void disconnect() {
		try {
			isConnected = false;
			out.writeObject(new ServerMessage(ServerSideMessage.Type.DISCONNECTED, nickname, null));
			in.close();
			out.close();
			socket.close();

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean hasNextMessage() {
		return !q.isEmpty();
	}

	@Override
	public ClientSideMessage getNextMessage() {
		return q.poll();
	}

	@Override
	public void sendOrder(Order order) {
		try {
			out.writeObject((new ServerMessage(
					ServerSideMessage.Type.NEW_ORDER, nickname, order)));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
